export default class SocketService {
  /**
   * 单例模式
   */
  static instance = null;
  static get Instance() {
    if (!this.instance) {
      this.instance = new SocketService();
    }
    return this.instance;
  }

  // 和服务器连接的socket对象
  ws = null;

  // 存储回调函数
  callBackMapping = {};

  // 和服务器连接是否成功标识
  connected = false;

  // 记录连接服务器websocket重试次数
  sendRetryCount = 0;

  // 记录重新连接产生的次数
  connectRetryCount = 0;

  // 定义连接服务器的方法
  connect() {
    // 连接服务器
    if (!window.WebSocket) {
      return console.log("您的浏览器不支持WebSocket");
    }
    this.ws = new WebSocket("ws://localhost:9998");

    // 连接成功的事件
    this.ws.onopen = () => {
      console.log("连接服务端成功...");
      this.connected = true;
      // 重置重新连接的次数
      this.connectRetryCount = 0;
    };

    // 1.连接失败的事件
    // 2.连接成功之后，服务器关闭的情况
    this.ws.onclose = () => {
      console.log("连接服务端失败...");
      this.connected = false;
      this.connectRetryCount ++;
      // 重试
      setTimeout(() => {
        this.connect();
      }, this.connectRetryCount * 500);
    };

    // 获取服务端发送过来的数据
    this.ws.onmessage = msg => {
      console.log("获取服务端发送过来的数据...:", msg.data);
      const recvData = JSON.parse(msg.data);
      const socketType = recvData.socketType;
      // 通过服务器端发送过来的数据中的socketType去匹配Mapping中存储的函数
      // 然后执行这个函数，将realData传给函数中的this.allData
      if (this.callBackMapping[socketType]) {
        const action = recvData.action;
        switch (action) {
          case "getData":
            const realData = JSON.parse(recvData.data);
            this.callBackMapping[socketType].call(this, realData);
            break;
          case "fullScreen":
            this.callBackMapping[socketType].call(this, recvData);
            break;
          case "themeChange":
            this.callBackMapping[socketType].call(this, recvData);
            break;
          default:
            break;
        }
      }
    };
  }

  // 回调函数的注册
  registerCallBack(socketType, callBack) {
    // 这里通过Mapping去存储了一个函数:getData(组件的中方法)
    this.callBackMapping[socketType] = callBack;
  }

  // 取消某一个回调函数
  unRegisterCallBack(socketType) {
    this.callBackMapping[socketType] = null;
  }

  // 发送数据的方法
  send(data) {
    // 判断是否连接成功
    if(this.connected){
      this.sendRetryCount = 0;
      this.ws.send(JSON.stringify(data));
    }else{
      this.sendRetryCount ++;
      //这里延迟，使得可以连接到服务器
      setTimeout(() => {
        this.ws.send(JSON.stringify(data));
      },this.sendRetryCount * 500);
    }
  }
}
